﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using FireStarter.CodeGeneration;
using FireStarterModeller.BO;
using NUnit.Framework;

namespace FireStarter.Test.CodeGeneration
{
    [TestFixture]
    public class TestUIVWGProjectGenerator : TestProjectGeneratorBase
    {
        private static UIVWGProjectGenerator CreateUIVWGProjectReadyToGenerate()
        {
            UIVWGProjectGenerator projectGenerator = new UIVWGProjectGenerator();
            CreateSolutionGenerator(projectGenerator);
            projectGenerator.ProjectPath = GetRootedPath(Path.Combine(TEST_PROJECTS_FOLDER, GetRandomString()));
            projectGenerator.ProjectName = "TestProject.UI.VWG";
            projectGenerator.SolutionGenerator.SolutionTypeName = GetRandomString();
            projectGenerator.ModelSolution.BOProjectName = GetRandomString();
            return projectGenerator;
        }

        protected override IProjectGenerator CreateProjectGenerator()
        {
            return new UIVWGProjectGenerator();
        }

        protected override IProjectGenerator CreateProjectReadyToGenerate()
        {
            return CreateUIVWGProjectReadyToGenerate();
        }

        [Test]
        public void TestGenerate_Fails_SolutionTypeNameNotSet()
        {
            //---------------Set up test pack-------------------
            IProjectGenerator projectGenerator = CreateProjectReadyToGenerate();
            projectGenerator.SolutionGenerator.SolutionTypeName = null;
            //---------------Assert Precondition----------------
            Assert.IsNull(projectGenerator.SolutionGenerator.SolutionTypeName);
            //---------------Execute Test ----------------------
            Exception exception = null;
            try
            {
                projectGenerator.Generate();
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            //---------------Test Result -----------------------
            Assert.IsNotNull(exception, "Exception Expected");
            Assert.IsInstanceOf(typeof(PropertyMissingException), exception);
            PropertyMissingException propertyMissingException = (PropertyMissingException)exception;
            Assert.AreEqual("SolutionTypeName", propertyMissingException.PropertyName);
        }

        [Test]
        public void Test_GenerateControlFactory_DualWINVWG_ReturnsTrue()
        {
            //---------------Set up test pack-------------------
            UIVWGProjectGenerator uiVWGProjectGenerator = new UIVWGProjectGenerator();
            uiVWGProjectGenerator.SolutionGenerator = new SolutionGenerator();
            uiVWGProjectGenerator.SolutionGenerator.SolutionTypeName = GenerationTypes.SOLUTION_TYPE_DUALWINVWG;
            //---------------Assert Precondition----------------
            Assert.AreEqual(GenerationTypes.SOLUTION_TYPE_DUALWINVWG, uiVWGProjectGenerator.SolutionGenerator.SolutionTypeName);
            //---------------Execute Test ----------------------
            bool actualGenerateControlFactory = uiVWGProjectGenerator.GenerateControlFactory();
            //---------------Test Result -----------------------
            Assert.IsTrue(actualGenerateControlFactory);
        }

        [Test]
        public void Test_GenerateControlFactory_Other_ReturnsFalse()
        {
            //---------------Set up test pack-------------------
            UIVWGProjectGenerator uiVWGProjectGenerator = new UIVWGProjectGenerator();
            uiVWGProjectGenerator.SolutionGenerator = new SolutionGenerator();
            uiVWGProjectGenerator.SolutionGenerator.SolutionTypeName = GenerationTypes.SOLUTION_TYPE_VWG;
            //---------------Assert Precondition----------------
            Assert.AreEqual(GenerationTypes.SOLUTION_TYPE_VWG, uiVWGProjectGenerator.SolutionGenerator.SolutionTypeName);
            //---------------Execute Test ----------------------
            bool actualGenerateControlFactory = uiVWGProjectGenerator.GenerateControlFactory();
            //---------------Test Result -----------------------
            Assert.IsFalse(actualGenerateControlFactory);
        }

        [Test]
        public void TestGenerate_Creates_ProjectFile_IfDoesNotExist()
        {
            //---------------Set up test pack-------------------
            UIVWGProjectGenerator uiVWGProjectGenerator = CreateUIVWGProjectReadyToGenerate();
            string projectFileName = uiVWGProjectGenerator.ProjectFileName;
            //---------------Assert Precondition----------------
            Assert.IsFalse(File.Exists(projectFileName));
            //---------------Execute Test ----------------------
            uiVWGProjectGenerator.Generate();
            //---------------Test Result -----------------------
            AssertProjectGeneratedCorrectly(uiVWGProjectGenerator);
        }

        private static void AssertProjectGeneratedCorrectly(UIVWGProjectGenerator uiVWGProjectGenerator)
        {
            string libFolderName = uiVWGProjectGenerator.SolutionGenerator.HabaneroReferencePath;
            libFolderName = Utilities.GetRelativePath(libFolderName, uiVWGProjectGenerator.ProjectPath);
            string projectFileName = uiVWGProjectGenerator.ProjectFileName;
            Assert.IsTrue(Directory.Exists(uiVWGProjectGenerator.ProjectPath));
            Assert.IsTrue(File.Exists(projectFileName));
            ProjectFileManager projectFileManager = new ProjectFileManager(projectFileName, CodeTemplateEnum.CSharpVisualStudio2005);
            Assert.AreEqual(OutputType.Library, projectFileManager.OutputType);
            string projectFileContents = File.ReadAllText(projectFileName);
            StringAssert.Contains(@"<Compile Include=""Properties\AssemblyInfo.cs"" />", projectFileContents);
            AssertHasReference(projectFileContents, string.Format(@"{0}\Habanero.Base.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\Habanero.BO.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\Habanero.Faces.Base.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\Habanero.Faces.VWG.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\log4net.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\Gizmox.WebGUI.Forms.dll", libFolderName));
            AssertHasReference(projectFileContents, string.Format(@"{0}\Gizmox.WebGUI.Common.dll", libFolderName));
        }

        [Test]
        public void TestGenerate_AddsControlFactory_IfDualWINVWG()
        {
            //---------------Set up test pack-------------------
            UIVWGProjectGenerator projectGenerator = CreateUIVWGProjectReadyToGenerate();
            projectGenerator.SolutionGenerator.SolutionTypeName = GenerationTypes.SOLUTION_TYPE_DUALWINVWG;
            //---------------Assert Precondition----------------
            Assert.AreEqual(GenerationTypes.SOLUTION_TYPE_DUALWINVWG, projectGenerator.SolutionGenerator.SolutionTypeName);
            //---------------Execute Test ----------------------
            projectGenerator.Generate();
            //---------------Test Result -----------------------
            string projectFileContents = File.ReadAllText(projectGenerator.ProjectFileName);
            string controlFactoryName = projectGenerator.SolutionGenerator.ModelSolution.ApplicationName + "ControlFactoryVWG.cs";
            StringAssert.Contains(@"<Compile Include=""" + controlFactoryName + @""" />", projectFileContents);
        }

        [Test]
        public void TestGenerate_DoesNotAddIControlFactory_IfOther()
        {
            //---------------Set up test pack-------------------
            UIVWGProjectGenerator projectGenerator = CreateUIVWGProjectReadyToGenerate();
            projectGenerator.SolutionGenerator.SolutionTypeName = GenerationTypes.SOLUTION_TYPE_VWG;
            //---------------Assert Precondition----------------
            Assert.AreEqual(GenerationTypes.SOLUTION_TYPE_VWG, projectGenerator.SolutionGenerator.SolutionTypeName);
            //---------------Execute Test ----------------------
            projectGenerator.Generate();
            //---------------Test Result -----------------------
            string projectFileContents = File.ReadAllText(projectGenerator.ProjectFileName);
            string controlFactoryName = projectGenerator.SolutionGenerator.ModelSolution.ApplicationName + "ControlFactoryVWG.cs";
            Assert.IsFalse(projectFileContents.Contains(@"<Compile Include=""" + controlFactoryName + @""" />"));
        }
    }
}
